package com.yunpeng.dishes.web.controllers;

import com.alibaba.fastjson.JSONArray;
import com.yunpeng.common.dto.Result;
import com.yunpeng.common.exception.BizException;
import com.yunpeng.common.util.ParametersCheckUtil;
import com.yunpeng.dishes.biz.services.IDataCountProcessService;
import com.yunpeng.dishes.biz.services.IDishesNutrientsService;
import com.yunpeng.dishes.biz.services.IFoodNutrientsService;
import com.yunpeng.dishes.common.constants.ConstantValues;
import com.yunpeng.dishes.common.dtos.business.DishesFoodSaveDTO;
import com.yunpeng.dishes.common.dtos.business.DishesSaveDTO;
import com.yunpeng.dishes.common.dtos.business.OrderDishesSnapshotDTO;
import com.yunpeng.dishes.common.enums.ResultCodeEnum;
import com.yunpeng.dishes.common.vo.DishesNutrientsVO;
import com.yunpeng.dishes.common.vo.FoodNutrientsVO;
import com.yunpeng.dishes.common.vo.OrderNutrientsVO;
import com.yunpeng.dishes.common.vo.data.SuggestNutrientsView;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.List;

/**
 * DishesNutrientsController
 *
 * @author : Moore(hemw)
 * @date : 2020-03-28
 */
@RestController
@RequestMapping("/nutrients/api")
public class DishesNutrientsController {


    @Resource
    private IDishesNutrientsService dishesNutrientsService;

    @Resource
    private IFoodNutrientsService foodNutrientsService;

    @Resource
    private IDataCountProcessService dataCountProcessService;

    /**
     * 根据食材名称获取食材营养成分表，精确匹配名称
     *
     * @param foodName
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "foodsNutrientsByName", method = RequestMethod.POST)
    public Result<FoodNutrientsVO> queryNutrientOfFoodByName(@RequestParam(name = "foodName") String foodName) {
        ParametersCheckUtil.isNotNull(foodName, "食材名称为空");
        FoodNutrientsVO foodNutrientsVO = foodNutrientsService.queryNutrientOfFoodByName(foodName);
        if (foodNutrientsVO != null) {
            return Result.success(foodNutrientsVO);
        }
        return Result.fail(ResultCodeEnum.NOT_EXISTS_DATA_FAILED);
    }

    /**
     * 根据食材名称，获取对应的食材名称、代码列表
     *
     * @param foodName
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "queryFoodNames", method = RequestMethod.POST)
    public Result<JSONArray> queryFoodNames(@RequestParam(name = "foodName") String foodName) {
        ParametersCheckUtil.isNotNull(foodName, "食材名称为空");
        JSONArray jsonArray = foodNutrientsService.queryFoodNames(foodName);
        if (jsonArray != null && !jsonArray.isEmpty()) {
            return Result.success(jsonArray);
        }
        return Result.fail(ResultCodeEnum.NOT_EXISTS_DATA_FAILED);
    }


    /**
     * 根据食材代码获取食材营养成分表
     *
     * @param foodCode
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "foodsNutrientsByCode", method = RequestMethod.POST)
    public Result<FoodNutrientsVO> queryNutrientOfFoodByCode(@RequestParam(name = "foodCode") String foodCode) {
        ParametersCheckUtil.isNotNull(foodCode, "食材代码为空");
        FoodNutrientsVO foodNutrientsVO = foodNutrientsService.queryNutrientsOfFoodByCode(foodCode);
        if (foodNutrientsVO != null) {
            return Result.success(foodNutrientsVO);
        }
        return Result.fail(ResultCodeEnum.NOT_EXISTS_DATA_FAILED);
    }


    /**
     * 根据菜品代码获取菜品营养成分表
     *
     * @param dishesCode
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "dishesNutrientsByCode", method = RequestMethod.POST)
    public Result<DishesNutrientsVO> queryNutrientOfDishesByCode(@RequestParam(name = "dishesCode") String dishesCode) {
        ParametersCheckUtil.isNotNull(dishesCode, "菜品代码为空");
        DishesNutrientsVO dishesNutrientsVO = dishesNutrientsService.queryNutrientsOfDishesByCode(dishesCode);
        if (dishesNutrientsVO != null) {
            return Result.success(dishesNutrientsVO);
        }
        return Result.fail(ResultCodeEnum.NOT_EXISTS_DATA_FAILED);
    }

    /**
     * 根据商家菜品id获取菜品营养成分表
     *
     * @param dishesId
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "dishesNutrientsById", method = RequestMethod.POST)
    public Result<DishesNutrientsVO> queryNutrientOfDishesById(@RequestParam(name = "dishesId") Long dishesId) {
        ParametersCheckUtil.isGreatThenZero(dishesId, "菜品id无效");
        DishesNutrientsVO dishesNutrientsVO = dishesNutrientsService.queryNutrientsOfDishesById(dishesId);
        if (dishesNutrientsVO != null) {
            return Result.success(dishesNutrientsVO);
        }
        return Result.fail(ResultCodeEnum.NOT_EXISTS_DATA_FAILED);
    }

    /**
     * 根据菜品名称查询参考菜品（左匹配）
     *
     * @param name
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "referenceDishesByName", method = RequestMethod.POST)
    public Result<List<DishesNutrientsVO>> queryReferenceDishesByName(@RequestParam(name = "name") String name) {
        ParametersCheckUtil.isNotNull(name, "菜品名称为空");
        List<DishesNutrientsVO> result = dishesNutrientsService.queryReferenceDishesListByName(name);
        if (result != null && !result.isEmpty()) {
            return Result.success(result);
        }
        return Result.fail(ResultCodeEnum.NOT_EXISTS_DATA_FAILED);
    }

    /**
     * 根据订单id获取订单维度的营养元素表
     *
     * @param orderId
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "orderNutrients", method = RequestMethod.POST)
    public Result<OrderNutrientsVO> queryOrderNutrients(@RequestParam(name = "orderId") Long orderId) {
        ParametersCheckUtil.isGreatThenZero(orderId, "订单id无效");
        OrderNutrientsVO result = dishesNutrientsService.queryOrderNutrients(orderId);
        if (result != null) {
            return Result.success(result);
        }
        return Result.fail(ResultCodeEnum.NOT_EXISTS_DATA_FAILED);
    }

    /**
     * 设置商户菜品为推荐菜品
     *
     * @param code
     * @param user
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "copyToDishesTemplate", method = RequestMethod.POST)
    public Result<Void> copyToDishesTemplate(@RequestParam(name = "code") String code, @RequestParam(name = "user") Long user) {
        ParametersCheckUtil.isNotNull(code, "菜品代码为空");
        ParametersCheckUtil.isGreatThenZero(user, "用户id无效");
        dishesNutrientsService.copyToDishesTemplate(code, user);
        return Result.success();
    }

    /**
     * 保存菜品食材
     *
     * @param dishesSaveDTO
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "saveDishesFood", method = RequestMethod.POST)
    public Result<Void> saveDishesFoodRelation(@RequestBody DishesSaveDTO dishesSaveDTO) {
        ParametersCheckUtil.isNotNull(dishesSaveDTO, "存储对象不能是空");
        ParametersCheckUtil.isNotBlank(dishesSaveDTO.getName(), "菜品名称不能为空");
        ParametersCheckUtil.isGreatThenZero(dishesSaveDTO.getWeight(), "菜品重量无效");
        ParametersCheckUtil.isNotNull(dishesSaveDTO.getUserId(), "用户id不能为空");
        ParametersCheckUtil.isNotNull(dishesSaveDTO.getMerchantId(), "商户id不能为空");
        ParametersCheckUtil.isNotNull(dishesSaveDTO.getMerchantDishesId(), "菜品id不能为空");
        ParametersCheckUtil.collectionIsNotNullOrderEmpty(dishesSaveDTO.getDishesFoodList(), "食材列表不能为空集");
        BigDecimal proportion = new BigDecimal("0");
        BigDecimal netContent = new BigDecimal("0");
        for (DishesFoodSaveDTO dishesFoodSaveDTO : dishesSaveDTO.getDishesFoodList()) {
            if (dishesFoodSaveDTO.getProportion() == null || dishesFoodSaveDTO.getProportion().doubleValue() <= 0) {
                String msg = String.format("食材：%s的占比错误，必须大于0", dishesFoodSaveDTO.getName());
                throw new BizException(ResultCodeEnum.PARAMETER_CHECK_FAILED.getValue(), msg);
            }
            if (dishesFoodSaveDTO.getNetContent() == null || dishesFoodSaveDTO.getNetContent().doubleValue() <= 0) {
                String msg = String.format("食材：%s的含量错误，必须大于0", dishesFoodSaveDTO.getName());
                throw new BizException(ResultCodeEnum.PARAMETER_CHECK_FAILED.getValue(), msg);
            }
            if (dishesFoodSaveDTO.getNetContent().subtract(dishesFoodSaveDTO.getProportion().multiply(dishesSaveDTO.getWeight())).abs().doubleValue() > ConstantValues.NET_PROPORTION_ABS) {
                String msg = String.format("食材：%s的重量与菜品重量的比例值错误！", dishesFoodSaveDTO.getName());
                throw new BizException(ResultCodeEnum.PARAMETER_CHECK_FAILED.getValue(), msg);
            }
            proportion = proportion.add(dishesFoodSaveDTO.getProportion());
            netContent = netContent.add(dishesFoodSaveDTO.getNetContent());
        }
        if (proportion.doubleValue() > 1) {
            throw new BizException(ResultCodeEnum.PARAMETER_CHECK_FAILED.getValue(), "食材占比总计超过1");
        }
        if (netContent.subtract(dishesSaveDTO.getWeight()).abs().doubleValue() > ConstantValues.NET_CONTENT_ABS) {
            String msg = String.format("食材总重量错误，与菜品重量误差在%d内.", ConstantValues.NET_CONTENT_ABS);
            throw new BizException(ResultCodeEnum.PARAMETER_CHECK_FAILED.getValue(), msg);
        }
        Boolean result = dishesNutrientsService.saveDishesFoodRelation(dishesSaveDTO);
        if (result) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

    /**
     * 保存订单菜品
     *
     * @param orderDishesSnapshotDTO
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "saveOrderDishes", method = RequestMethod.POST)
    public Result<Void> saveOrderNutrientsSnapshot(@RequestBody OrderDishesSnapshotDTO orderDishesSnapshotDTO) {
        ParametersCheckUtil.isNotNull(orderDishesSnapshotDTO, "存储对象不能是空");
        ParametersCheckUtil.isNotNull(orderDishesSnapshotDTO.getOrderId(), "订单id不能为空");
        ParametersCheckUtil.isNotNull(orderDishesSnapshotDTO.getOrderCode(), "订单编号不能为空");
        ParametersCheckUtil.collectionIsNotNullOrderEmpty(orderDishesSnapshotDTO.getDishesIds(), "商户菜品id集合不能为空集");
        ParametersCheckUtil.isNotNull(orderDishesSnapshotDTO.getMerchantId(), "商户id不能为空");
        dishesNutrientsService.saveOrderNutrientsSnapshot(orderDishesSnapshotDTO);
        return Result.success();
    }

    /**
     * 用户的营养建议
     *
     * @param userId
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "suggestNutrientsView4User", method = RequestMethod.POST)
    public Result<SuggestNutrientsView> suggestNutrientsView4User(@RequestParam(name = "user") Long userId) {
        ParametersCheckUtil.isNotNull(userId, "用户不能是空");
        return Result.success(dataCountProcessService.getSuggestNutrientsView4User(userId));
    }

}
